from py2neo import Node,NodeMatcher,Path,Graph,RelationshipMatcher
from typing import List,Dict,Any,Tuple
from config import *
graph = Graph(url, auth=(user, password))
node_matcher = NodeMatcher(graph)
relationship_matcher = RelationshipMatcher(graph)
def getAllNameNode() ->List[str]:
   nodes =  node_matcher.match("事故").all()
   ret: List[str] = []
   for node in nodes:
      if node["name"] not in ret: 
         ret.append(node["name"])
   return ret

def tran2Dict(node:Node,src):
    label = list(node.labels)[0]
    if label =="事故":
        label = "事故名称"
    src[label] = {
      "name": node["name"],
      "des": node["desc"] if node["desc"] else node["attr"],
    }
    if src[label]["des"] is None: 
        src[label]["des"] = ""

def getGraph(name: List[str]) -> Dict[str,Dict[str,Dict[str,str]]]:
    ret = {}
    for n in name:
        nodes =  node_matcher.match("事故").where(name=n).first()
        ret [n] = {}
        tran2Dict(nodes,ret[n])
        rels = list(relationship_matcher.match([nodes],r_type=None))
        for r in rels:
            tran2Dict(r.end_node,ret[n])
    return ret

def getListItem(graph:Dict[str,Dict[str,Dict[str,str]]],key:str)-> List[str]:
   ret = []
   for _,v in graph.items():
      if key in v:
         ret.append(v[key]["name"])
   return ret
def getRelation(graph:Dict[str,Dict[str,Dict[str,str]]],key:Tuple[str,str])-> Tuple[List[Dict[str,Any]],List[Dict[str,Any]],List[str]]:
    nodes = []
    rels = []
    category = {}
    cid = 0
    if  len(key) == 2 and key[1]!="all":
        for _,v in graph.items():
            if key[0] in v and key[1] == v[key[0]]["name"]:
                if key[0] not in category:
                    category[key[0]] = cid
                    cid += 1
                centerNode = v[key[0]]
                centerNode["symbolSize"] = 70 # type: ignore
                centerNode["category"] = category[key[0]]
                if centerNode["des"] is None:
                    centerNode["des"] = ""
                nodes.append(centerNode)
                for k,v in v.items():
                    if k != key[0]:
                        if k not in category:
                            category[k] = cid
                            cid += 1
                        tmp = v.copy()
                        tmp["category"] = category[k]
                        if tmp["des"] is None:
                            tmp["des"] = ""
                        nodes.append(tmp)
                        rels.append({
                            "source": v["name"],
                            "target":centerNode["name"],
                            "des": v["des"] if v["des"] else "",
                        })
            else:
                if key[0] in v:
                    print("not found",v[key[0]]['name'])
    else:   
        for _,v in graph.items():
            if key[0] in v :
                if key[0] not in category:
                    category[key[0]] = cid
                    cid += 1
                centerNode = v[key[0]]
                centerNode["symbolSize"] = 70 # type: ignore
                centerNode["category"] = category[key[0]]
                if centerNode["des"] is None:
                    centerNode["des"] = ""
                nodes.append(centerNode)
                for k,v in v.items():
                    if k != key[0]:
                        if k not in category:
                            category[k] = cid
                            cid += 1
                        tmp = v.copy()
                        tmp["category"] = category[k]
                        if tmp["des"] is None:
                            tmp["des"] = ""
                        nodes.append(tmp)
                        rels.append({
                            "source": v["name"],
                            "target":centerNode["name"],
                            "des": v["des"] if v["des"] else "",
                        })
    c =sorted(category, key=lambda k: category[k])
    return nodes,rels,c
import re
def getEventType(graph:Dict[str,Dict[str,Dict[str,str]]]) :
    ret = {}
    merge = ["坠落","高坠","高处坠落"]
    for _,v in graph.items():
        if "事故类型" in v:
            name = re.sub(r'\d+$',"",v["事故类型"]["name"])
            if  name not in ret: # type: ignore
                if name in merge:
                    name = "坠落"
                ret[name] = [v["事故名称"]]
            else:
                ret[name].append(v["事故名称"])
    return ret
if __name__ == "__main__":
    l = getAllNameNode()
    g= getGraph(l)
    print(g)
    r = getListItem(g,"事故名称")
    print(r)

    
